package com.qwiki.text;

import java.util.List;

/**
 * @author xgu
 * 
 *         May 29, 2012
 */
public abstract class Node
{
  public char[] buffer;
  public int start;
  public int end;
  public boolean parsed;

  public abstract List<Node> getChildren();

  public boolean isCategory()
  {
    return false;
  }

  public String getCategory()
  {
    return null;
  }

  public abstract String getText();

  // {
  // return getOriginalText();
  // }

  public String getOriginalText()
  {
    if (!parsed)
      throw new IllegalStateException("not parsed yet");
    return new String(buffer, start, end - start);
  }

  public int getLength()
  {
    if (!parsed)
      throw new IllegalStateException("not parsed yet");
    return end - start;
  }

  public abstract boolean parse(char[] buffer, int start);

  public static boolean match(char[] buffer, int index, String key)
  {
    if (index + key.length() > buffer.length)
      return false;
    for (int i = 0; i < key.length(); i++)
    {
      if (Character.toLowerCase(buffer[index + i]) != key.charAt(i))
        return false;
    }
    return true;
  }

  /**
   * @param buffer
   * @param index
   * @param key
   * @param skip
   * @return where the match starts and -1 if not matched
   */
  public static int match(char[] buffer, int index, String key, char skip)
  {
    while (index < buffer.length && (buffer[index] == '\n' || buffer[index] == '\r' || buffer[index] == skip))
    {
      index++;
    }
    if (index + key.length() > buffer.length)
      return -1;
    for (int i = 0; i < key.length(); i++)
    {
      if (Character.toLowerCase(buffer[index + i]) != key.charAt(i))
        return -1;
    }
    return index;
  }

  /**
   * @param buffer
   * @param key
   * @param index
   * @return location where the key starts, -1 if not found
   */
  public static int find(char[] buffer, String key, int index)
  {
    out: while (index < buffer.length)
    {
      if (index + key.length() > buffer.length)
        return -1;
      for (int i = 0; i < key.length(); i++)
      {
        if (Character.toLowerCase(buffer[index + i]) != key.charAt(i))
        {
          index++;
          continue out;
        }
      }
      return index;
    }
    return -1;
  }
}
